﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Diagnostics;
using System.Reflection;
using System.ComponentModel;
using Lilium.Configuration;
using Lilium.Web.Mvc.AjaxControlToolkit;

namespace Lilium.Web.Mvc.Configuration
{
	/// <summary>
	/// Ресурс клиентского скрипта для ACT
	/// </summary>
	public sealed class ToolkitScriptResourceElement: ConfigurationElement
	{
		public ClientScriptResource GetClientScriptResource()
		{
			return new ClientScriptResource(
				Name,
				GetResourceName(),
				GetResourceTypeName(),
				GetResourceAssembly());
		}

		#region public string Name

		private const string NamePropertyName = "name";

		/// <summary>
		/// Имя элемента.
		/// </summary>
		/// <remarks>
		/// ИСпользуется для идентификации элемента и формирования имени ресурса, если имя ресурса не указано явно.
		/// </remarks>
		[ConfigurationPropertyAttribute(NamePropertyName)]
		public string Name { [DebuggerNonUserCodeAttribute] get { return (string)base[NamePropertyName]; } [DebuggerNonUserCodeAttribute] set { base[NamePropertyName] = value; } }

		#endregion

		#region public Assembly ResourceAssembly

		private const string ResourceAssemblyPropertyName = "resourceAssembly";

		[ConfigurationPropertyAttribute(ResourceAssemblyPropertyName)]
		[TypeConverter(typeof(AssemblyNameConverter))]
		public Assembly ResourceAssembly { [DebuggerNonUserCodeAttribute] get { return (Assembly)base[ResourceAssemblyPropertyName]; } [DebuggerNonUserCodeAttribute] set { base[ResourceAssemblyPropertyName] = value; } }

		#endregion

		#region public string ResourceName

		private const string ResourceNamePropertyName = "resourceName";

		[ConfigurationPropertyAttribute(ResourceNamePropertyName)]
		public string ResourceName { [DebuggerNonUserCodeAttribute] get { return (string)base[ResourceNamePropertyName]; } [DebuggerNonUserCodeAttribute] set { base[ResourceNamePropertyName] = value; } }

		#endregion

		#region public string ResourceTypeName

		private const string ResourceTypeNamePropertyName = "resourceTypeName";

		[ConfigurationPropertyAttribute(ResourceTypeNamePropertyName)]
		public string ResourceTypeName { [DebuggerNonUserCodeAttribute] get { return (string)base[ResourceTypeNamePropertyName]; } [DebuggerNonUserCodeAttribute] set { base[ResourceTypeNamePropertyName] = value; } }

		#endregion

		private Assembly GetResourceAssembly()
		{
			return ResourceAssembly != null || AjaxControlToolkitScriptElement == null 
				? ResourceAssembly 
				: AjaxControlToolkitScriptElement.GetResourceAssembly();
		}

		private string GetResourceName()
		{
			if (string.IsNullOrEmpty(ResourceName) && (AjaxControlToolkitScriptElement != null))
			{
				var library = AjaxControlToolkitScriptElement.ScriptResourceLibrary as EmbeededResourceLibraryElement;
				if (library != null)
					return library.ResourceNamespace + "." + Name;
			}
			return ResourceName;
		}

		private string GetResourceTypeName()
		{
			if (string.IsNullOrEmpty(ResourceTypeName) && (AjaxControlToolkitScriptElement != null))
			{
				var library = AjaxControlToolkitScriptElement.ScriptResourceLibrary as EmbeededResourceLibraryElement;
				if (library != null)
					return library.Name + "." + Name;
			}
			return ResourceTypeName;
		}

		#region internal AjaxControlToolkitScriptElement AjaxControlToolkitScriptElement

		private EmbeededToolkitScriptElement m_AjaxControlToolkitScriptElement;

		internal EmbeededToolkitScriptElement AjaxControlToolkitScriptElement { [DebuggerNonUserCodeAttribute] get { return m_AjaxControlToolkitScriptElement; } [DebuggerNonUserCodeAttribute] set { m_AjaxControlToolkitScriptElement = value; } }

		#endregion
	}
}